package com.weedsdream.app.function

import androidx.compose.ui.geometry.Offset
import kotlin.math.abs

/**当原点在凸多边形内部时，计算多边形外一点与原点的连线，和多边形某条边的交点
 * @param point 外部点
 * @param list 多边形顶点
 * @return 交点*/
fun findIntersection(point: Offset, list: List<Offset>): Offset {
    for (i in list.indices) {
        val p1 = list[i]
        val p2 = list[(i + 1) % list.size] // 下一个顶点，循环回到第一个顶点
        val res = lineIntersection(point, p1, p2)
        if (res != null) return res
    }
    return Offset.Zero
}

/**浮点计算误差*/
private const val inaccuracy = 0.01

/**从原点向point发出射线，与p1,p2线段的交点
 * @return null 无交点*/
fun lineIntersection(point: Offset, p1: Offset, p2: Offset): Offset? {
    val x: Float //交点x坐标
    val y: Float //交点y坐标
    val k = if (abs(point.x) < inaccuracy) null else point.y / point.x//原点到point射线斜率，null说明垂直x轴
    val k12 = if (abs(p1.x - p2.x) < inaccuracy) null else (p2.y - p1.y) / (p2.x - p1.x)
    val c12 = if (k12 != null) p1.y - k12 * p1.x else 0f //p1p2线截距
    if (k == null && k12 == null) return null//平行线
    if (k != null && k12 != null && abs(k - k12) < inaccuracy) return null//平行线

    if (k == null) {
        x = point.x
        y = k12!! * x + c12
    } else if (k12 == null) {
        x = p1.x
        y = k * x
    } else {
        x = c12 / (k - k12)
        y = k * x
    }

    // 检查交点是否在 p1 和 p2 的范围内
    return if (x < minOf(p1.x, p2.x) || x > maxOf(p1.x, p2.x)) null// 交点不在线段x范围内
    else if (y < minOf(p1.y, p2.y) || y > maxOf(p1.y, p2.y)) null//不在线段y范围
    else if (x < minOf(point.x, 0f) || x > maxOf(point.x, 0f)) null//不在连线x范围
    else if (y < minOf(point.y, 0f) || y > maxOf(point.y, 0f)) null//不在连线y范围
    else Offset(x, y)
}
